package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.form.DVehicleClassifyForm;
import cn.huiyunche.base.service.interfaces.DVehicleClassifyService;
import cn.huiyunche.base.service.interfaces.query.DVehicleClassifyQueryConditions;
import cn.huiyunche.base.service.mappers.DFuelPriceEffectiveMapper;
import cn.huiyunche.base.service.mappers.DRouteVehiclePriceEffectiveMapper;
import cn.huiyunche.base.service.mappers.DVehicleClassifyMapper;
import cn.huiyunche.base.service.mappers.DVehiclePreKilometerFeeEffectiveMapper;
import cn.huiyunche.base.service.mappers.ext.DVehicleClassifyExtMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.DVehicleClassifyVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @FileName: cn.huiyunche.driver.service.impl
 * @Description: Description
 * @author: Aaron
 * @date: 2017/3/2 下午8:28
 */
@Service
public class DVehicleClassifyServiceImpl implements DVehicleClassifyService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DVehicleClassifyServiceImpl.class);

    @Autowired
    private DVehicleClassifyMapper dVehicleClassifyMapper;

    @Autowired
    private DVehicleClassifyExtMapper dVehicleClassifyExtMapper;

    @Autowired
    private DVehiclePreKilometerFeeEffectiveMapper dVehiclePreKilometerFeeEffectiveMapper;

    @Autowired
    private DFuelPriceEffectiveMapper dFuelPriceEffectiveMapper;

    @Autowired
    private DRouteVehiclePriceEffectiveMapper dRouteVehiclePriceEffectiveMapper;

    @Override
    public List<DVehicleClassify> selectByFuelTypeId(Integer fuelTypeId) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.selectByFuelTypeId params : {}", fuelTypeId);

        if (null == fuelTypeId) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectByFuelTypeId param fuelTypeId must not be null");
            throw new IllegalArgumentException("燃油类型主键不能为空");
        }

        DVehicleClassifyExample example = new DVehicleClassifyExample();
        example.createCriteria().andFuelTypeIdEqualTo(fuelTypeId);

        return dVehicleClassifyMapper.selectByExample(example);
    }

    @Override
    public String add(DVehicleClassifyForm form, BindingResult br) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.add param : {}", form);

        if (null == form) {
            LOGGER.error("DVehicleClassifyServiceImpl.add param form must not be null");
            throw new IllegalArgumentException("车型分类表单不能为空");
        }

        //验证表单
        verificationForm(br);

        //业务验证 车型分类编码唯一
        verificationBusiness(form);

        DVehicleClassify vehicleClassify = new DVehicleClassify();
        BeanUtils.copyProperties(form, vehicleClassify);
        vehicleClassify.setEnable(true);

        dVehicleClassifyMapper.insertSelective(vehicleClassify);

        return vehicleClassify.getId();
    }

    private void verificationBusiness(DVehicleClassifyForm form) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.verificationBusinessByAdd param : {}", form);

        if (null == form) {
            LOGGER.error("DVehicleClassifyServiceImpl.verificationBusinessByAdd param form must not be null");
            throw new IllegalArgumentException("车型分类表单不能为空");
        }

        this.verificationClassifyIdOrClassifyNameUnique(form.getId(), form.getVehicleClassifyName(), form.getVehicleClassifyId());
    }

    /**
     * 查询未激活车型单公里油费
     *
     * @param vehicleTypeId
     * @return
     */
    private List<DVehiclePreKilometerFeeEffective> selectNotEffective(String vehicleTypeId) {
        LOGGER.info("DVehicleClassifyServiceImpl.selectNotEffective param : {}", vehicleTypeId);

        if (null == vehicleTypeId) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectNotEffective param vehicleTypeId must not be null");
            throw new IllegalArgumentException("车型主键不能为空");
        }

        DVehiclePreKilometerFeeEffectiveExample example = new DVehiclePreKilometerFeeEffectiveExample();
        example.createCriteria().andVehicleTypeIdEqualTo(vehicleTypeId).andInvalidDateIsNull();
        List<DVehiclePreKilometerFeeEffective> list = dVehiclePreKilometerFeeEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            DVehiclePreKilometerFeeEffective effective = list.get(0);
            Date currentDate = new Date();
            if (null == effective.getInvalidDate() && currentDate.before(effective.getEffectiveDate())) {
                return list;
            }
        }
        return null;
    }

    private void verificationForm(BindingResult br) throws Exception {

        if (null == br) {
            LOGGER.error("DVehicleClassifyServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            LOGGER.error("DVehicleClassifyServiceImpl.add error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    @Override
    public DVehicleClassify selectByPrimaryId(String id) throws Exception {
        return this.dVehicleClassifyMapper.selectByPrimaryKey(id);
    }

    @Override
    public String update(DVehicleClassifyForm form, BindingResult br) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.add param : {}", form);

        if (null == form) {
            LOGGER.error("DVehicleClassifyServiceImpl.add param form must not be null");
            throw new IllegalArgumentException("车型分类表单不能为空");
        }

        //验证表单
        verificationForm(br);

        //业务验证 车型分类编码唯一
        verificationBusiness(form);

        DVehicleClassify vehicleClassify = new DVehicleClassify();
        BeanUtils.copyProperties(form, vehicleClassify);
        dVehicleClassifyMapper.updateByPrimaryKeySelective(vehicleClassify);

//        // 更新车型单公里油费
//        updateDvehiclePreKilometerFeeEffective(vehicleClassify);

//        // 更新车型线路总运费
//        udpateRouteVehicleTotalPrice(vehicleClassify);

        return vehicleClassify.getId();
    }

    /**
     * 更新车型线路总运费
     *
     * @param vehicleClassify
     */
    private void udpateRouteVehicleTotalPrice(DVehicleClassify vehicleClassify) {
        LOGGER.info("DVehicleClassifyServiceImpl.udpateRouteVehicleTotalPrice params : {}", vehicleClassify);
        if (null == vehicleClassify) {
            LOGGER.info("DVehicleClassifyServiceImpl.udpateRouteVehicleTotalPrice vehicleClassify must not be null");
            throw new IllegalArgumentException("车型不能为空");
        }

        List<DRouteVehiclePriceEffective> list = this.selectDRouteVehicle(vehicleClassify.getId());
        if (CollectionUtils.isNotEmpty(list)) {
            list.stream().forEach(vl -> {
                DVehiclePreKilometerFeeEffective effective = selectActivedByEffectiveDate(vl.getVehicleTypeId(), vl.getEffectiveDate());
                if (null != effective) {
                    vl.setTotalPrice(effective.getPerKmOilFee().add(vl.getLabourServicesPrice()));
                    dRouteVehiclePriceEffectiveMapper.updateByPrimaryKeySelective(vl);
                }
            });
        }
    }

    private DVehiclePreKilometerFeeEffective selectActivedByEffectiveDate(String vehicleTypeId, Date effectiveDate) {
        LOGGER.info("DVehicleClassifyServiceImpl.selectActivedByEffectiveDate params : {}, {}", vehicleTypeId, effectiveDate);

        if (null == vehicleTypeId || "0" == vehicleTypeId) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectActivedByEffectiveDate param vehicleTypeId must not be null");
            throw new IllegalArgumentException("车型分类主键不能为空");
        }

        if (null == effectiveDate) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectActivedByEffectiveDate param effectiveDate must not be null");
            throw new IllegalArgumentException("激活时间不能为空");
        }

        List<DVehiclePreKilometerFeeEffective> list;

        DVehiclePreKilometerFeeEffectiveExample example = new DVehiclePreKilometerFeeEffectiveExample();
        example.createCriteria().andVehicleTypeIdEqualTo(vehicleTypeId)
                .andEffectiveDateLessThanOrEqualTo(effectiveDate)
                .andInvalidDateIsNull();

        list = dVehiclePreKilometerFeeEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            DVehiclePreKilometerFeeEffectiveExample example1 = new DVehiclePreKilometerFeeEffectiveExample();
            example1.createCriteria().andVehicleTypeIdEqualTo(vehicleTypeId)
                    .andEffectiveDateLessThanOrEqualTo(effectiveDate)
                    .andInvalidDateGreaterThan(new Date());

            list = dVehiclePreKilometerFeeEffectiveMapper.selectByExample(example1);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }

        return null;
    }

    private List<DRouteVehiclePriceEffective> selectDRouteVehicle(String vehicleClassifyId) {
        LOGGER.info("DVehicleClassifyServiceImpl.selectDRouteVehicle params : {}", vehicleClassifyId);
        if (null == vehicleClassifyId) {
            LOGGER.info("DVehicleClassifyServiceImpl.selectDRouteVehicle vehicleClassifyId is must not be null");
            throw new IllegalArgumentException("车型ID不能为空");
        }
        DRouteVehiclePriceEffectiveExample example = new DRouteVehiclePriceEffectiveExample();
        example.createCriteria().andVehicleTypeIdEqualTo(vehicleClassifyId).andEffectiveDateGreaterThan(new Date()).andInvalidDateIsNull();

        List<DRouteVehiclePriceEffective> effectives = dRouteVehiclePriceEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(effectives)) {
            return effectives;
        }
        return null;
    }

    /**
     * 更新车型单公里油费
     *
     * @param vehicleClassify
     */
    private void updateDvehiclePreKilometerFeeEffective(DVehicleClassify vehicleClassify) {
        LOGGER.info("DVehicleClassifyServiceImpl.updateDvehiclePreKilometerFeeEffective params : {}", vehicleClassify);
        if (null == vehicleClassify) {
            LOGGER.info("DVehicleClassifyServiceImpl.updateDvehiclePreKilometerFeeEffective vehicleClassify is must not be null");
            throw new IllegalArgumentException("车型不能为空");
        }
        // 当前车型生效单公里油价变更
        List<DVehiclePreKilometerFeeEffective> selectNotEffective = selectNotEffective(vehicleClassify.getId());
        if (CollectionUtils.isNotEmpty(selectNotEffective)) {
            selectNotEffective.stream().forEach(e -> {
                // 获取当前车型生效燃油市场价
                BigDecimal marketPrice = gainFuelMarketPrice(e.getFuelPriceId());
                e.setPerKmOilFee(vehicleClassify.getFuelConsumption().divide(BigDecimal.valueOf(100)).multiply(marketPrice));
                dVehiclePreKilometerFeeEffectiveMapper.updateByPrimaryKeySelective(e);
            });
        }
    }

    /**
     * 通过燃油类型ID获取市场价
     *
     * @param fuelPriceId
     * @return
     */
    private BigDecimal gainFuelMarketPrice(Integer fuelPriceId) {
        LOGGER.info("DVehicleClassifyServiceImpl.gainFuelMarketPrice param fuelPriceId: {}", fuelPriceId);
        if (null == fuelPriceId) {
            LOGGER.info("DVehicleClassifyServiceImpl.gainFuelMarketPrice param fuelPriceId is must not be null");
            throw new IllegalArgumentException("燃油类型ID不能为空");
        }

        DFuelPriceEffectiveExample example = new DFuelPriceEffectiveExample();
        example.createCriteria().andIdEqualTo(fuelPriceId).andEffectiveDateGreaterThanOrEqualTo(new Date()).andInvalidDateIsNull();
        List<DFuelPriceEffective> fEffective = this.dFuelPriceEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(fEffective)) {
            return fEffective.get(0).getMarketPrice();
        }
        return null;
    }

    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, DVehicleClassifyQueryConditions conditions) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);

        if (null == conditions) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectListByConditions param conditions must not be null");
            throw new IllegalArgumentException("车型分类查询条件不能为空");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " vc.update_time DESC";
        }

        DVehicleClassifyExample example = new DVehicleClassifyExample();
        DVehicleClassifyExample.Criteria criteria = example.createCriteria();

        if (null != conditions.getVehicleClassifyId()) {
            criteria.andVehicleClassifyIdEqualTo(conditions.getVehicleClassifyId());
        }

        if (StringUtils.isNotBlank(conditions.getVehicleClassifyName())) {
            criteria.andVehicleClassifyNameLikeInsensitive("%" + conditions.getVehicleClassifyName() + "%");
        }

        if (null != conditions.getFuelTypeId()) {
            criteria.andFuelTypeIdEqualTo(conditions.getFuelTypeId());
        }

        if (null != conditions.getFuelConsumption()) {
            criteria.andFuelConsumptionGreaterThanOrEqualTo(conditions.getFuelConsumption());
        }

        if (null != conditions.getEnable()) {
            criteria.andEnableEqualTo(conditions.getEnable());
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(dVehicleClassifyExtMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }

        List<DVehicleClassifyVo> list = dVehicleClassifyExtMapper.selectByExample(example);
        map.put("list", list);

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }

    @Override
    public void verificationClassifyIdOrClassifyNameUnique(String id, String vehicleClassifyName, String vehicleClassifyId) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.selectByVehicleClassifyId param : {}", vehicleClassifyId);

        if (null == vehicleClassifyId) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectByVehicleClassifyId param vehicleClassifyId must not be null");
            throw new IllegalArgumentException("车型分类编码不能为空");
        }

        DVehicleClassifyExample example = new DVehicleClassifyExample();
        example.createCriteria().andVehicleClassifyIdEqualTo(vehicleClassifyId);

        List<DVehicleClassify> list = dVehicleClassifyMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            if (id != null && list.get(0).getId() == id) {
                return;
            }
            LOGGER.error("DVehicleClassifyServiceImpl.verificationBusinessByAdd business error");
            throw new BusinessException("车型分类编码已经存在");
        }

        DVehicleClassifyExample example1 = new DVehicleClassifyExample();
        example1.createCriteria().andVehicleClassifyNameEqualTo(vehicleClassifyName);

        List<DVehicleClassify> list1 = dVehicleClassifyMapper.selectByExample(example1);
        if (CollectionUtils.isNotEmpty(list1)) {
            if (id != null && list1.get(0).getId() == id) {
                return;
            }
            LOGGER.error("DVehicleClassifyServiceImpl.verificationBusinessByAdd business error");
            throw new BusinessException("车型分类名称已经存在");
        }
    }

    @Override
    public int enableOrDisabled(String id, Boolean enableOrDisabled) {
        LOGGER.info("DVehicleClassifyServiceImpl.enableOrDisabled params id: {}, enableOrDisabled: {}", id, enableOrDisabled);
        if (null == id) {
            LOGGER.error("DVehicleClassifyServiceImpl.enableOrDisabled param id must not be null");
            throw new IllegalArgumentException("车型分类编码不能为空");
        } else if (null == enableOrDisabled) {
            LOGGER.error("DVehicleClassifyServiceImpl.enableOrDisabled param enableOrDisabled must not be null");
            throw new IllegalArgumentException("车型分类编码不能为空");
        }
        DVehicleClassify classify = this.dVehicleClassifyMapper.selectByPrimaryKey(id);
        if (null != classify) {
            classify.setEnable(enableOrDisabled);
            this.dVehicleClassifyMapper.updateByPrimaryKeySelective(classify);
        }
        return 0;
    }

    @Override
    public DVehicleClassify selectByVehicleClassifyId(String vehicleClassifyId) {
        LOGGER.info("DVehicleClassifyServiceImpl.selectByVehicleClassifyId param : {}", vehicleClassifyId);

        if (null == vehicleClassifyId || "0" == vehicleClassifyId) {
            LOGGER.error("DVehicleClassifyServiceImpl.selectByVehicleClassifyId param vehicleClassifyId must not be null");
            throw new IllegalArgumentException("车型分类主键不能为空");
        }

        DVehicleClassifyExample example = new DVehicleClassifyExample();
        example.createCriteria().andVehicleClassifyIdEqualTo(vehicleClassifyId);

        List<DVehicleClassify> list = dVehicleClassifyMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }

        return null;
    }

    @Override
    public void del(Integer id) throws Exception {
        LOGGER.info("DVehicleClassifyServiceImpl.del param : {}", id);

        if ( null == id || 0 == id.intValue()  ) {
            LOGGER.error("DVehicleClassifyServiceImpl.del param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        dVehicleClassifyMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<DVehicleClassify> findByName(String vehicleClassifyName) {
        return dVehicleClassifyExtMapper.findByName(vehicleClassifyName);
    }

    @Override
    public List<DVehicleClassify> findVehicleClassify(String vehicleClassifyName) {
        return dVehicleClassifyExtMapper.findVehicleClassify(vehicleClassifyName, 0 , 10);
    }
}
